#pragma once

#include <iostream>

struct MapData
{
	char data[15];
	MapData() {
		memset(data, -1, sizeof(data));
	}
};

template<typename T>
struct MapNode
{
	T* node_data;
	MapNode* next;
	MapNode* pre;

	MapNode()
	: node_data(0), next(0), pre(0)
	{
	}

	~MapNode() {
		if (node_data != NULL) {
			delete node_data;
			node_data = NULL;
		}
	}

};

template<typename T>
class DBLinkedList
{
	MapNode<T>* head;
	MapNode<T>* cur;
	int curidx;
	int total;

public:
	DBLinkedList<T>() {
		head = new MapNode<T>;
		head->pre = head;
		head->next = head;
		cur = head;
		curidx = -1;
		total = 0;
	}

	~DBLinkedList<T>() {
		clear();
		delete head;
	}

	bool insert(T* data) {
		MapNode<T>* node = new MapNode<T>;
		node->node_data = data;
		node->pre = head->pre;
		head->pre->next = node;
		node->next = head;
		head->pre = node;

		total ++;
		cur = node;
		curidx = total - 1;
		return true;
	}

	bool remove(int idx) {
		if (idx >= total)
			return false;
		moveTo(idx);
		cur = cur->pre;
		MapNode<T>* node = cur->next;
		cur->next = node->next;
		node->next->pre = cur;
		total --;
		delete node;
		cur = cur->next;
		curidx = idx;
		return true;
	}

	void left() {
		cur = cur->pre;
		curidx --;
		if (curidx == -2)
			curidx = total - 1;
	}

	void right() {
		cur = cur->next;
		curidx ++;
		if (curidx == total)
			curidx = -1;
	}

	void moveTo(int idx) {
		if (idx < total) {
			while (getCurIndex() != idx) {
				if (getCurIndex() < idx) {
					right();
				} else {
					left();
				}
			}
		} else {
			while (cur->next != head)
				cur = cur->next;
			while (getCurIndex() != idx) {
				T* newNode = new T;
				insert(newNode);
			}
		}
	}

	T* getCur() {
		return cur->node_data;
	}

	int size() {
		return total;
	}

	int getCurIndex() {
		return curidx;
	}

	void clear() {
		MapNode<T>* temp = head->next;
		while (temp != head) {
			MapNode<T>* tmp = temp->next;
			temp->next->pre = temp->pre;
			temp->pre->next = temp->next;
			delete temp;
			temp = tmp;
		}
		cur = head;
		curidx = -1;
		total = 0;
	}
};